package com.tiku.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiku.common.ResultJson;
import com.tiku.controller.DTO.UserParamDTO;
import com.tiku.controller.TO.UserParamTO;
import com.tiku.controller.TO.UserRegisterTo;
import com.tiku.entity.*;
import com.tiku.mapper.UserActiveTypeMapper;
import com.tiku.service.StaticImgService;
import com.tiku.service.UserInfoService;
import com.tiku.mapper.UserInfoMapper;
import com.tiku.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.util.*;

/**
 *
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
        implements UserInfoService {


    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private StaticImgService staticImgService;



    @Value("${caishikao.kefuLink}")
    private String kefuLink;
    //头像max大小
    @Value("${img.MAX_FILE_SIZE}")
    private long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
    @Value("${img.IMG_PATH}")
    //图片保存路径
    private String IMG_PATH = "D:\\work\\project\\tiku\\img";

    @Value("${img.DEFAULT}")
    private String DEFAULT;


    @Override
    public ResultJson login(UserParamTO userParamTO) {

        Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userParamTO.getUsername(), userParamTO.getPassword()));
        if (Objects.isNull(authenticate)) {
            return ResultJson.error("登录异常");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        UserInfo userInfo = (UserInfo) loginUser.getEntity();
        String id = userInfo.getId();
        String jwt = JwtUtil.createJWT(id);
        redisCache.setCacheObject("user:" + id, jwt);
        Map<String, String> map = new HashMap<String, String>();
        map.put("token", jwt);
        map.put("studentId", userInfo.getStudentId());
        map.put("nickName", userInfo.getNickName());
        map.put("avatar", userInfo.getAvatar());
        return ResultJson.success(map);
    }

    @Override
    public ResultJson register(UserRegisterTo userRegisterTo) {
        String phone = userRegisterTo.getPhone().trim();
        String password = userRegisterTo.getPassword().trim();
        UserInfo one = getUserInfoByPhone(phone);
        if (Objects.nonNull(one)) {
            return ResultJson.error("账号已经存在!");
        }

        //检验验证码是否正确
        String capCode = userRegisterTo.getCapCode().trim();
        String cacheObject = redisCache.getCacheObject(phone);
        if (StringUtils.isEmpty(capCode)
                || StringUtils.isEmpty(cacheObject)
                || !capCode.equals(cacheObject)) {
            return ResultJson.error("验证码错误！");
        }

        //验证通过 入库
        UserInfo userInfo = new UserInfo();
        userInfo.setUserPhone(phone);
        userInfo.setPassword(passwordEncoder.encode(password));
        userInfo.setAvatar("默认.jpg");
        userInfo.setSex(2);
        String studentId = generateRandomSixDigit();
        userInfo.setNickName("神圣学员" + studentId);
        //生成学号
        userInfo.setStudentId(studentId);
        BeanUtil.beforeInsert(userInfo);
        userInfoMapper.insert(userInfo);
        redisCache.deleteObject(phone);

        // 发送验证码

        return ResultJson.success("注册成功！");


    }

    /**
     * 生成学号
     *
     * @return
     */
    public String generateRandomSixDigit() {
        Random random = new Random();
        while (true) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 6; i++) {
                sb.append(random.nextInt(10));
            }
            Long aLong = userInfoMapper.selectCount(new LambdaQueryWrapper<>(UserInfo.class).eq(UserInfo::getStudentId, sb.toString()));
            if (aLong > 1) {
                continue;
            }

            return sb.toString();
        }


    }

    @Override
    public ResultJson send(String phone,String type) {
        boolean isPhone = RegCheck.validateMobileNumber(phone);
        if (!isPhone){
            return ResultJson.error("手机号格式错误！");
        }
        //校验手机号是否已经存在
/*        UserInfo one = getUserInfoByPhone(phone);
        if (Objects.nonNull(one)) {
            return ResultJson.error("账号已经存在!");
        }*/
        try {
            Sample.sendSms(phone,type);
        } catch (Exception e) {
            return ResultJson.sysError();
        }
        return ResultJson.success("发送成功！");
    }

    @Override
    public ResultJson updatePwd(UserRegisterTo userRegisterTo) {

        String phone = userRegisterTo.getPhone().trim();
        boolean isPhone = RegCheck.validateMobileNumber(phone);
        if (!isPhone){
            return ResultJson.error("手机号格式错误！");
        }

        UserInfo userInfo = getUserInfoByPhone(phone);
        if (Objects.isNull(userInfo)){
            return ResultJson.error("账户不存在");
        }
        String capCode = userRegisterTo.getCapCode().trim();
        String cacheObject = redisCache.getCacheObject(phone);
        //验证验证码
        if (StringUtils.isEmpty(capCode)
                || StringUtils.isEmpty(cacheObject)
                || !capCode.equals(cacheObject)) {
            return ResultJson.error("验证码错误！");
        }

        BeanUtil.beforeUpdate(userInfo);
        //取出密码进行加密 存入表中更改
        String password = userRegisterTo.getPassword().trim();
        userInfo.setPassword(passwordEncoder.encode(password));
        boolean b = userInfoMapper.updateById(userInfo)>0;
        redisCache.deleteObject("user:"+ThreadLocalUtil.getThreadLocal());
        redisCache.deleteObject(phone);
        return b? ResultJson.success("密码更改成功,请重新登录！"):ResultJson.sysError();
    }

    @Override
    public UserInfo getUserInfoByPhone(String phone) {
        UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<>(UserInfo.class).eq(UserInfo::getUserPhone, phone));
        return userInfo;
    }

    @Override
    public ResultJson upAvatar(MultipartFile avatarFile) {
        if (avatarFile != null && !avatarFile.isEmpty()) {
            if (avatarFile.getSize() <= MAX_FILE_SIZE) {
                // 处理文件上传逻辑
                // 创建上传目录（如果不存在）
                File uploadDir = new File(IMG_PATH);
                if (!uploadDir.exists()) {
                    uploadDir.mkdirs();
                }
                try {
                    //拼接文件名
                    String fileName = avatarFile.getOriginalFilename();
                    String newFileName = Instant.now().toEpochMilli() + "_" + fileName;
                    File destinationFile = new File(uploadDir, newFileName);
                    //存入本地
                    Files.copy(avatarFile.getInputStream(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                    //更新用户数据
                    UserInfo userInfo = userInfoMapper.selectById(ThreadLocalUtil.getThreadLocal());
                    userInfo.setAvatar(newFileName);
                    BeanUtil.beforeUpdate(userInfo);
                    userInfoMapper.updateById(userInfo);
                    return ResultJson.success("头像上传成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    return ResultJson.sysError();
                }

            } else {
                return ResultJson.error("文件过大，超过限制大小。");
            }
        } else {
            return ResultJson.error("未选择头像文件。");
        }
    }

    @Override
    public ResultJson getAvatar(String img) {
        try {
            File imageFile = new File(IMG_PATH + "/" + img);
            if (!imageFile.exists()) {
                return ResultJson.error("未找到资源！");
            }
            byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            return ResultJson.success(base64Image);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultJson.sysError();
        }
    }

    @Override
    public ResultJson upSex(Integer sex) {
        if (sex<0||sex>2){
            return ResultJson.error("参数错误！");
        }
        //获取当前登录用户信息
        UserInfo userInfo = getUserInfoByThreadLoacl();

        userInfo.setSex(sex);
        BeanUtil.beforeUpdate(userInfo);
        boolean b = userInfoMapper.updateById(userInfo)>0;

        return b? ResultJson.success("修改成功"):ResultJson.sysError();
    }

    @Override
    public ResultJson upNickName(String nickName) {
        if (StringUtils.isEmpty(nickName)){
            return ResultJson.error("参数错误!");
        }
        nickName=nickName.trim();
        //获取当前登录用户信息
        UserInfo userInfo = getUserInfoByThreadLoacl();
        userInfo.setNickName(nickName);
        BeanUtil.beforeUpdate(userInfo);

        boolean b = userInfoMapper.updateById(userInfo)>0;
        return b? ResultJson.success("修改成功"):ResultJson.sysError();
    }

    @Override
    public ResultJson getUserParam() {

        UserInfo userInfo = getUserInfoByThreadLoacl();
        StaticImg img = staticImgService.getOne(new LambdaQueryWrapper<StaticImg>().eq(StaticImg::getType, "1"));

        UserParamDTO userParamDTO=new UserParamDTO(userInfo.getNickName(),MaskingUtil.maskPhoneNumber(userInfo.getUserPhone()),userInfo.getSex(),userInfo.getAvatar(),img.getPath(),userInfo.getToDay(),kefuLink);
        if (StringUtils.isEmpty(userParamDTO.getAvatar())) {
            userParamDTO.setAvatar(DEFAULT);
        }

        return ResultJson.success(userParamDTO);
    }

    @Override
    public ResultJson updatePhone(String phone, String code) {
        if (StringUtils.isEmpty(phone)||StringUtils.isEmpty(code)){
            return ResultJson.error("手机号验证码不能为空！");
        }
        UserInfo userInfoByThreadLoacl = getUserInfoByThreadLoacl();
        if (phone.trim().equals(userInfoByThreadLoacl.getUserPhone())){
            return ResultJson.error("手机号未发生变化!");
        }

        String cacheObject= redisCache.getCacheObject(phone.trim());
        //验证验证码
        if (StringUtils.isEmpty(cacheObject)
                || !code.trim().equals(cacheObject)) {
            return ResultJson.error("验证码错误！");
        }

        userInfoByThreadLoacl.setUserPhone(phone);

        BeanUtil.beforeUpdate(userInfoByThreadLoacl);
        boolean b = userInfoMapper.updateById(userInfoByThreadLoacl)>0;
        redisCache.deleteObject("user:"+ThreadLocalUtil.getThreadLocal());
        redisCache.deleteObject(phone);


        return b?ResultJson.success("更改成功！请重新登录"):ResultJson.sysError();
    }

    @Override
    public ResultJson updateToDay(String day) {
        String userId = ThreadLocalUtil.getThreadLocal();

        userInfoMapper.updateToDay(userId,day);


        return ResultJson.success();
    }


    public UserInfo getUserInfoByThreadLoacl() {
        String threadLocal = ThreadLocalUtil.getThreadLocal();
        return getById(threadLocal);
    }
}




